﻿
using Dapper;
using hdal;
using hentity;

using hutil;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace hwms {
    /**
   *┌────────────────────────────────────────────────┐
   *│　描    述：Component                                                    
   *│　作    者：sgj                                              
   *│　版    本：1.0                                              
   *│　创建时间：2020/9/2 11:28:16                        
   *└────────────────────────────────────────────────┘
   **/
    public class TaskPersistenceUtil {

        /// <summary>
        /// 移库任务
        /// </summary>

        /// <returns></returns>
        static public long move(long goodDiff ,AbsCoreStock cs ,IDbConnection conn ,IDbTransaction trans)  {
            //将该浅货位的货物移动到该浅货位同组下的空货位  csdList[0].rLoctionId==null ? 0: csdList[0].rLoctionId
            var whLoc = conn.GetById<CoreWhLoc>(cs.locId ,trans);
            if( whLoc == null ) {
                throw new Exception(cs.boxCode + "不在库存");
            }

            CoreWhLoc des = LocConfig.moveSelect(whLoc ,conn ,trans);//每个moveGroup 必须有一个空货位共移库
            if( des == null ) {
                throw new Exception(cs.id + "托盘号为：" + cs.boxCode + " 的移库任务下发失败，没有空货位！");
            }
            long taskId = InsertTask( goodDiff ,( int ) cs.locId ,des.id ,conn ,trans ,cs.id ,cs.boxCode ,"0" ,null,1);

            long taskParamId = moveCoreTaskParam(conn ,trans ,null ,taskId ,( int ) cs.locId ,( int ) des.id ,0);
            StockUtil.UpdateStock(conn ,trans ,cs.id ,StockStatus.移动中);
            CsdUtil.UpdateStockDetail(conn ,trans ,cs.id );
            CoreUtil.UpdataWhLoc(conn ,trans ,( int ) cs.locId,goodDiff);
            CoreUtil.UpdataWhLoc(conn ,trans ,des.id,goodDiff);
            return taskParamId;
        }
       

        static public TaskResDto createOutTask(long goodDiff ,String info ,IDbConnection conn ,IDbTransaction trans ,AbsCoreStock cs ,int des ,String waveNo ,long relay = 0 ,int bussType = 1) {
            ParamContent pc = new ParamContent();
            long taskId = InsertTask(goodDiff,cs.locId,des ,conn ,trans ,cs.id ,cs.boxCode ,waveNo,info,bussType);
            long paramTaskId = moveCoreTaskParam(conn ,trans ,pc ,taskId ,( int ) cs.locId ,des ,relay);
            StockUtil.UpdateStock(conn ,trans ,cs.id ,StockStatus.移动中);
            CsdUtil.UpdateStockDetail(conn ,trans ,cs.id);
            CoreUtil.UpdataWhLoc(conn ,trans ,( long ) cs.locId,goodDiff); 
            return new TaskResDto() { taskId = taskId ,paramId = paramTaskId };
        }
        static public TaskResDto createInOutTask(long goodDiff ,String info,IDbConnection conn ,IDbTransaction tran ,AbsCoreStock cs ,int des ,String waveNo ,long relay = 0 ,int bussType = 1 ,ParamContent pc = null)  {
            long taskId2 = InsertTask(goodDiff,( int ) cs.locId ,des ,conn ,tran ,cs.id ,cs.boxCode ,waveNo,info,bussType);
            long paramTaskId = moveCoreTaskParam(conn ,tran ,pc ,taskId2 ,( int ) cs.locId ,des ,relay);
            StockUtil.UpdateStock(conn ,tran ,cs.id ,StockStatus.移动中);
            CsdUtil.UpdateStockDetail(conn ,tran ,cs.id);
            return new TaskResDto() { taskId = taskId2 ,paramId = paramTaskId };
        }

        /// <summary>
        /// 下发入库任务
        static public TaskResDto createInTask(long goodDiff,AbsCoreStock cs ,int des , IDbConnection conn ,IDbTransaction tran ,long relay = 0 ,String waveNo="" ,String info=null  ,int bussType = 1 ,ParamContent pc = null) {
            if( 0 == des || null == cs ) {
                throw new Exception(cs.id + " 入库任务下发失败！");
            }
            if( String.IsNullOrEmpty(waveNo) ) {
                waveNo = cs.id+"";
            }

            long taskId2 = InsertTask(goodDiff,( int ) cs.locId ,des ,conn ,tran ,cs.id ,cs.boxCode ,waveNo,info,bussType);
            long paramTaskId = moveCoreTaskParam(conn ,tran ,pc ,taskId2 ,( int ) cs.locId ,( int ) des ,relay);
           
            StockUtil.UpdateStock(conn ,tran ,cs.id ,StockStatus.移动中);
            CsdUtil.UpdateStockDetail(conn ,tran ,cs.id);
            CoreUtil.UpdataWhLoc(conn ,tran ,( int ) des,goodDiff);
            return new TaskResDto() { taskId = taskId2 ,paramId = paramTaskId };
        }


        static public TaskResDto createOutInTask(long goodDiff ,String info ,IDbConnection conn ,IDbTransaction tran ,AbsCoreStock cs ,int des ,String waveNo,long relay = 0 ,int bussType = 1 ,ParamContent pc = null)  {
            long taskId2 = InsertTask( goodDiff ,( int ) cs.locId,des ,conn ,tran ,cs.id ,cs.boxCode , waveNo,info,bussType);

            long paramTaskId = moveCoreTaskParam(conn ,tran ,pc ,taskId2 ,( int ) cs.locId ,des ,relay);
            StockUtil.UpdateStock(conn ,tran ,cs.id ,StockStatus.移动中);
            CsdUtil.UpdateStockDetail(conn ,tran ,cs.id);
            CoreUtil.UpdataWhLoc(conn ,tran ,( int ) cs.locId,goodDiff);
            CoreUtil.UpdataWhLoc(conn ,tran ,des,goodDiff);
            return new TaskResDto() { taskId = taskId2 ,paramId = paramTaskId };
        }
        static public TaskResDto createPkTask(long pkId,long goodDiff ,IDbConnection conn ,IDbTransaction tran ,AbsCoreStock cs ,int des ,String waveNo ,String info=null ,long relay = 0 ,ParamContent pc = null) {
            int src = ( int ) cs.locId;
            long taskId2 = InsertTask(goodDiff,src ,src ,conn ,tran ,cs.id ,cs.boxCode ,waveNo ,info ,1);
            long paramTaskId = moveCoreTaskParam(conn ,tran ,pc ,taskId2 ,src ,des ,relay);
            StockUtil.UpdateStock(conn ,tran ,cs.id ,StockStatus.盘库中);
            CsdUtil.pkStockDetail(conn ,tran ,cs.id,pkId);
            CoreUtil.UpdataWhLoc(conn ,tran ,src,goodDiff);
            return new TaskResDto() { taskId = taskId2 ,paramId = paramTaskId };
        }
       


        static public long InsertTask(long goodDiff ,int start ,long des ,IDbConnection con ,IDbTransaction tran ,long stockId ,String boxCode ,String waveNo ,String info  ,int bussType) {

            CoreTask task = new CoreTask();
            task.id = WMSIdUtil.getId();
            task.stockId = stockId;
            task.boxCode = boxCode;
            task.Status = ( int ) CoreTaskStatus.执行中;
            task.createTime = WMSIdUtil.GetTime();
            task.bussType = bussType;
            task.src = start;
            task.des = ( int ) des;
            if( String.IsNullOrEmpty(info) ) {
                task.info = createCoreTaskInfo(task);
            } else {
                task.info = info;
            }
            task.waveNo = waveNo;
            task.goodDiff = goodDiff;
            con.InsertNoNull<CoreTask>(task ,tran);
            return task.id;
        }



        static protected String createCoreTaskInfo(CoreTask task) {

            return String.Format("从{0}到{1}" ,stnToCrane(task.src) ,stnToCrane(task.des));
        }
        static String stnToCrane(long loc) {
            if( LocConfig.isLoc(loc) ) {
                return (loc + 10000) / 20000 + "号垛机" + loc;
            } else {
                return loc.ToString();
            }
        }
        static public long InsertCoreTaskParam(IDbConnection Connection ,IDbTransaction transaction ,long stockDetailId ,ParamContent content ,long taskId ,int src ,int des ,TaskParamType paramType ,long relyId ,CoreTaskParamStatus status = CoreTaskParamStatus.可以接收任务) {
            //任务明细添加
            CoreTaskParam param = new CoreTaskParam();
            param.id = WMSIdUtil.getId();
            param.stockDetailId = stockDetailId;
            param.taskId = taskId; //task.id
            param.status = ( int ) status;//新建状态
            param.src = src;
            param.cStn = param.src;
            param.des = des;

            param.taskNo = TaskNoUtil.getTaskNo(Connection ,transaction);
            param.relyParamId = relyId;
            if( content != null ) {
                param.param = ObjStrUtil.toJosn(content);
            }

            param.type = ( byte ) paramType;
            param.createTime = WMSIdUtil.GetTime();
            Connection.InsertNoNull<CoreTaskParam>(param ,transaction);
            return param.id;
        }
        static public long moveCoreTaskParam(IDbConnection Connection ,IDbTransaction transaction ,ParamContent content ,long taskId ,int src ,int des ,long relyId) {
            //任务明细添加
            return InsertCoreTaskParam(Connection ,transaction ,0 ,content ,taskId ,src ,des ,TaskParamType.托盘搬运 ,relyId ,CoreTaskParamStatus.可以接收任务);
        }
        static public void check<CS>(CS cs ,List<CoreTaskParam> coreTaskParam) {
            foreach( CoreTaskParam p in coreTaskParam ) {
                if( p.status == ( int ) CoreTaskParamStatus.执行完成 ) {
                    throw new Exception("任务过程" + p.id + "已经完成,无法删除任务");
                }
            }
        }
        static public List<CoreTaskParam> GetListByTaskId(IDbConnection conn ,IDbTransaction tran ,long taskId) {
            string sql = "select * from Core_task_param where task_Id=@taskId";
            return conn.Query<CoreTaskParam>(sql ,new { taskId = taskId } ,tran).ToList();
        }
        static public CoreTask getCoreTask(IDbConnection Connection ,IDbTransaction transaction ,long taskId) {
            String sql = @"select * from Core_task where id=@taskId ";
            List<CoreTask> list = Connection.Query<CoreTask>(sql ,new {
                taskId = taskId
            } ,transaction).ToList();
            if( list.Count < 1 ) {
                throw new Exception(taskId + " 任务不存在!");
            }
            return list[0];
        }



    }
}
